const CreditAmount = require('../entity/credit/creditamount');
const CreditRecord = require('../entity/credit/creditrecord');
const Order = require('../entity/product/order');
const UserBase = require('../entity/user/userbase');
const TaskIncome = require('../entity/account/taskincome');
const AdminUser = require('../entity/user/adminuser');

const OrderStatus = require('../module/const/OrderStatus');
const CreditRecordStatus = require('../module/const/CreditRecordStatus');

const userService = require('./user');
const timeTool = require('../module/tool/time');

const { CommonServiceError } = require('../module/error/svcerror');
const {
    requestPaymentOrder,
    creditPaymentSceneId,
    queryPaymentOrder,
    addPaymentOrderStatusListener
} = require('./payment-merchant');

let hasPaymentOrderStatusListener = false;
if (!hasPaymentOrderStatusListener) {
    hasPaymentOrderStatusListener = true;
    addPaymentOrderStatusListener(creditPaymentSceneId, async (paymentOrderId, paymentOrderStatus) => {
        const CreditRecordModel = new CreditRecord().getModel();
        const CreditAmountModel = new CreditAmount().getModel();
        const creditRecordData = await new CreditRecord().getModel().findOne({
            paymentOrderId: paymentOrderId
        });
        if (!creditRecordData) {
            return;
        }
        if (paymentOrderStatus === '3' && creditRecordData.status === CreditRecordStatus.Payed.value) {
            // 设置信用金为已还款
            await CreditRecordModel.findOneAndUpdate({ _id: creditRecordData._id }, {
                status: CreditRecordStatus.repayment.value,
                repaymentTime: timeTool.getCurrentTimestamp()
            });
            // 退还信用金
            await CreditAmountModel.findOneAndUpdate({ userId: creditRecordData.userId }, { $inc: { useCreditAmount: -creditRecordData.useAmount } });

            // 生成订单收入
            const TaskIncomeEntity = new TaskIncome();
            const TaskIncomeModel = TaskIncomeEntity.getModel();
            const AdminUserModel = new AdminUser().getModel();

            const orderData = await getOrderData(creditRecordData.orderId);
            const adminUserData = await AdminUserModel.findOne({ areaId: orderData.areaId });

            if (!await TaskIncomeModel.exists({
                adminId: adminUserData._id,
                areaId: orderData.areaId,
                orderId: creditRecordData.orderId
            })) {
                await TaskIncomeEntity.getDoc({
                    adminId: adminUserData._id,
                    areaId: orderData.areaId,
                    price: orderData.price,
                    orderId: creditRecordData.orderId
                }).save();
            }

            return true;
        } else {
            return false;
        }
    }).then(() => {
        console.log('addPaymentOrderStatusListener success');
    });
}

async function getOrderData (orderId) {
    // 查询订单数据
    const orderModel = new Order().getModel();
    return orderModel.findById(orderId);
}

// 开通信用金支付 --已优化
async function openCreditPayment (userId, creditAmount, isEnable) {
    const userInfo = await userService.getUserInfo(userId);

    const CreditAmountEntity = new CreditAmount();
    const CreditAmountModel = CreditAmountEntity.getModel();

    if (await CreditAmountModel.exists({ userId })) {
        throw new CommonServiceError('不可重复开通一个用户信用金！');
    }

    await CreditAmountEntity.getDoc({
        userId: UserBase.toObjectId(userId),
        areaId: UserBase.toObjectId(userInfo.authAreaId),
        creditAmount,
        useCreditAmount: 0,
        isEnable: isEnable,
        createTime: timeTool.getCurrentTimestamp()
    }).save();
    return 1;
}
// 设置信用金信息 --已优化
async function setCreditInfo (userId, creditAmount, isEnable) {
    const CreditAmountModel = new CreditAmount().getModel();
    if (!await CreditAmountModel.exists({ userId })) {
        throw new CommonServiceError('请先开通信用金！');
    }

    const creditAmountData = await CreditAmountModel.findOne({ userId });
    // 设置信用金额不能低于已使用的额度
    if (creditAmount < creditAmountData.useCreditAmount) {
        throw new CommonServiceError('信用金额不能低于已使用的额度！');
    }
    // 更新
    await CreditAmountModel.updateOne({ userId }, { creditAmount, isEnable });
    return 1;
}

// 扣除信用金 --已优化
async function deductCreditAmount (orderId, userId, areaId, price) {
    // 换算单位（分换元）
    price = price / 100;

    const CreditRecordEntity = new CreditRecord();
    const CreditAmountModel = new CreditAmount().getModel();
    const creditAmountData = await CreditAmountModel.findOne({ userId: userId, isEnable: true });

    if (!creditAmountData) {
        throw new CommonServiceError('信用金无效！');
    }
    if (creditAmountData.creditAmount - creditAmountData.useCreditAmount < price) {
        throw new CommonServiceError('信用金额度不足！');
    }

    // 增加信用金使用数量
    await CreditAmountModel.updateOne({ userId }, { $inc: { useCreditAmount: price } });
    // 产生信用金使用记录
    await CreditRecordEntity.getDoc({
        userId,
        areaId,
        orderId,
        useAmount: price,
        createTime: timeTool.getCurrentTimestamp(),
        status: CreditRecordStatus.Payed.value
    }).save();

    return 1;
}
// 退还信用金 --已优化
async function sendBackCreditAmount (userId, price, orderId) {
    // 查询订单数据
    const orderData = await getOrderData(orderId);
    if (orderData.price !== price) {
        throw new CommonServiceError('退款金额有误！');
    }

    if (userId !== orderData.userId.toString()) {
        throw new CommonServiceError('信用金退还对象有误！');
    }

    if (orderData.status === OrderStatus.Payed.value) {
        // 退还信用金
        const CreditAmountModel = new CreditAmount().getModel();
        await CreditAmountModel.findOneAndUpdate({ userId }, { $inc: { useCreditAmount: -price / 100 } });

        // 设置信用金使用记录为已取消
        const CreditRecordModel = new CreditRecord().getModel();
        await CreditRecordModel.findOneAndUpdate({ userId, orderId }, { status: CreditRecordStatus.Cancel.value, cancelTime: timeTool.getCurrentTimestamp() });
    }
    return 1;
}

// 信用金还款 --已优化
async function creditRepayment (userId, price, orderId) {
    const userInfo = await userService.getUserInfo(userId);

    // 订单完成后才能还款
    const orderData = await getOrderData(orderId);
    if (orderData.status !== OrderStatus.Finished.value) {
        throw new CommonServiceError('订单未完成');
    }

    const CreditRecordModel = new CreditRecord().getModel();
    const creditRecordData = await CreditRecordModel.findOne({ orderId });

    if (userInfo._id.toString() !== userId) {
        throw new CommonServiceError('还款对象有误');
    }
    if (creditRecordData.status !== CreditRecordStatus.Payed.value) {
        throw new CommonServiceError('信用金使用记录状态异常!');
    }

    // 微信还款
    let returnData = {};
    const useAmount = Math.round(creditRecordData.useAmount * 100);
    if (useAmount > 0) {
        const {
            paySign,
            orderId
        } = await requestPaymentOrder(creditPaymentSceneId, userInfo.openid, useAmount, '大力蛮牛信用金还款下单');
        creditRecordData.paymentOrderId = orderId;
        returnData.paySign = paySign;
        returnData.creditRecordId = creditRecordData._id;
        await creditRecordData.save();
    }
    return returnData;
}
// 支付回调（是否支付成功）
async function creditPaymentNotify (creditRecordId) {
    const CreditRecordModel = new CreditRecord().getModel();
    const CreditAmountModel = new CreditAmount().getModel();

    const creditRecordData = await CreditRecordModel.findById(CreditRecord.toObjectId(creditRecordId));
    const paymentOrderData = await queryPaymentOrder(creditRecordData.paymentOrderId);
    if (paymentOrderData.status === '3' && creditRecordData.status === CreditRecordStatus.Payed.value) {
        // 设置信用金为已还款
        await CreditRecordModel.findOneAndUpdate({ _id: CreditRecord.toObjectId(creditRecordId) }, {
            status: CreditRecordStatus.repayment.value,
            repaymentTime: timeTool.getCurrentTimestamp()
        });
        // 退还信用金
        await CreditAmountModel.findOneAndUpdate({ userId: creditRecordData.userId }, { $inc: { useCreditAmount: -creditRecordData.useAmount } });

        // 生成订单收入
        const TaskIncomeEntity = new TaskIncome();
        const TaskIncomeModel = TaskIncomeEntity.getModel();
        const AdminUserModel = new AdminUser().getModel();

        const orderData = await getOrderData(creditRecordData.orderId);
        const adminUserData = await AdminUserModel.findOne({ areaId: orderData.areaId });

        if (!await TaskIncomeModel.exists({
            adminId: adminUserData._id,
            areaId: orderData.areaId,
            orderId: creditRecordData.orderId
        })) {
            await TaskIncomeEntity.getDoc({
                adminId: adminUserData._id,
                areaId: orderData.areaId,
                price: orderData.price,
                orderId: creditRecordData.orderId
            }).save();
        }

        return true;
    } else {
        return false;
    }
}

// 查询用户信用金使用记录
async function getUserCreditRecord (userId, offset, rows) {
    offset = parseInt(offset);
    rows = parseInt(rows);

    // const userData = await userService.getUserInfo(userId);
    const CreditRecordModel = new CreditRecord().getModel();

    const res = await CreditRecordModel.aggregate([
        {
            $match: {
                userId: CreditRecord.toObjectId(userId)
                // areaId: CreditRecord.toObjectId(userData.authAreaId)
            }
        },
        { $sort: { createTime: -1 } },
        {
            $lookup: {
                from: 'order',
                localField: 'orderId',
                foreignField: '_id',
                as: 'orderInfo'
            }
        },
        {
            $unwind: { path: '$orderInfo' }
        },
        {
            $facet: {
                total: [
                    { $count: 'total' }
                ],
                data: [
                    { $skip: offset },
                    { $limit: rows }
                ]
            }
        }
    ]);
    const count = res[0].total[0] ? res[0].total[0].total : 0;
    const data = res[0].data;
    return { count, data };
}

// 后台偿还信用金
async function payCreditRecord (creditRecordId) {
    const CreditRecordModel = new CreditRecord().getModel();
    const CreditAmountModel = new CreditAmount().getModel();
    const creditRecordData = await CreditRecordModel.findById(creditRecordId);
    if (creditRecordData.status !== CreditRecordStatus.Payed.value) {
        throw new CommonServiceError('信用金状态有误！');
    }
    const orderData = await getOrderData(creditRecordData.orderId);
    if (orderData.status !== OrderStatus.Finished.value) {
        throw new CommonServiceError('订单未完成');
    }

    const price = orderData.price;
    // const orderId = orderData._id;
    // 设置信用金为已还款
    await CreditRecordModel.findByIdAndUpdate(creditRecordId, {
        status: CreditRecordStatus.repayment.value,
        repaymentTime: timeTool.getCurrentTimestamp(),
        prepayId: '管理员后台偿还'
    });
    // 退还信用金额度
    await CreditAmountModel.findOneAndUpdate({ userId: creditRecordData.userId }, { $inc: { useCreditAmount: -price / 100 } });

    // 生成订单收入
    // const TaskIncomeEntity = new TaskIncome();
    // const TaskIncomeModel = TaskIncomeEntity.getModel();
    // const AdminUserModel = new AdminUser().getModel();
    //
    // const adminUserData = await AdminUserModel.findOne({ areaId: orderData.areaId });
    // if (!await TaskIncomeModel.exists({ adminId: adminUserData._id, areaId: orderData.areaId, orderId })) {
    //     await TaskIncomeEntity.getDoc({ adminId: adminUserData._id, areaId: orderData.areaId, price: orderData.price, orderId }).save();
    // }
    return 1;
}

module.exports = {
    openCreditPayment,
    setCreditInfo,
    deductCreditAmount,
    sendBackCreditAmount,
    creditRepayment,
    creditPaymentNotify,
    getUserCreditRecord,
    payCreditRecord
};
